package com.se.hospitalmonitoring;

import java.util.ArrayList;
import java.util.HashMap;

public class BedAssignment {

	private static BedAssignment instance = null;
	private final HashMap<Long, PatientRecord> assignments = new HashMap<Long, PatientRecord>();
	private final ArrayList<Long> beds = new ArrayList<Long>();
	private static long lastPatientId = 0L;
	private static Object patientIdMutex = new Object();

	/**
	 * Private constructor
	 */
	private BedAssignment() {
	}

	/**
	 * Gets the singleton instance of this class
	 * 
	 * @return The singleton instance of this class
	 */
	public static BedAssignment getInstance() {
		if (instance == null)
			instance = new BedAssignment();
		return instance;
	}

	/**
	 * Adds a bed to the pool of beds
	 * 
	 * @param bedId
	 *            The id of the new bed
	 * @return True if the bed was new and was added, false otherwise
	 */
	public boolean addBed(Long bedId) {
		if (!beds.contains(bedId)) {
			beds.add(bedId);
			return true;
		}
		return false;
	}

	/**
	 * Removes the bed with the given id
	 * 
	 * @param bedId
	 *            The bed id to remove
	 */
	public void removeBed(Long bedId) {
		beds.remove(bedId);
	}

	/**
	 * Assigns the patient to the given bed
	 * 
	 * @param bedId
	 *            The id of the bed to assign
	 * @param patient
	 *            The patient to assign to the bed
	 * @return True on success, false if a patient is already assigned the bed
	 */
	public boolean assignBed(Long bedId, PatientRecord patient) {
		if (assignments.get(bedId) == null && beds.contains(bedId)) {
			assignments.put(bedId, patient);
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 * Gets the patient assigned to the given bed
	 * 
	 * @param bedId
	 *            The bed id to lookup the patient
	 * @return The patient record for the bed
	 */
	public PatientRecord getPatientByBed(long bedId) {
		return assignments.get(bedId);
	}

	/**
	 * Unassigns the given bed
	 * 
	 * @param bedId
	 *            The id of the bed to unassign
	 */
	public void unassignBed(Long bedId) {
		assignments.put(bedId, null);
	}

	/**
	 * Generates a patient id. Patient id is guaranteed to be unique
	 * 
	 * @return A new patient id
	 */
	public static long generatePatientId() {
		synchronized (patientIdMutex) {
			lastPatientId++;
			return lastPatientId;
		}
	}
}
